<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<link rel="shortcut icon" href="../../share/img/logo.png">
		<link rel="stylesheet" href="../../share/css/main.css">
		<script src="../../share/js/jquery-1.11.3.min.js" type="text/javascript" charset="utf-8"></script>
		<script src="../../share/js/util.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body class="p-10">
		<h1>对象</h1>
		<div class="row">
			<div class="col-1">
				<section>
					<h3>基础</h3>
					<div>
						<button onclick="test02()">普通函数</button>
						<button onclick="test03()">构造函数</button>
						<button onclick="test04()">对象原型</button>
						<button onclick="test05()">函数调用</button>
					</div>
				</section>
				<section>
					<h3>定义属性</h3>
					<div>
						<button onclick="test01()">测试</button>
					</div>
				</section>
				<section>
					<h3>数组</h3>
					<div>
						<button onclick="test11()">创建数组</button>
						<button onclick="test12()">增删元素</button>
						<button onclick="test13()">遍历数组</button>
						<button onclick="test14()">slice</button>
						<button onclick="test15()">splice</button>
						<button onclick="test16()">删除测试</button>
					</div>
				</section>
				<section>
					<h3>继承</h3>
					<button onclick="test21()">原型继承</button>
				</section>
			</div>
			<div class="col-1">
			</div>
			<div class="col-1">
				<ul id="log" class="d-list mt-10"></ul>
			</div>
		</div>
		<script>
			function test01() {
				let user = {};
				Object.defineProperty(user, "name", {
					get() {
						console.log('getting ...');
						return this.name;
					},
					set(val) {
						// console.log('setting ...');
						this.name = val;
					}
				});
				// user.name = "Tom";
				// console.log(user.name);
			}

			function test02() {
				// let car = buildCar();
				// console.log("普通调用后返回: ", car);

				let r = f01();
				console.log("普通调用返回: ", r)
			}

			function test03() {
				// let car = new buildCar();
				// console.log("new 方式调用后返回: ", car);

				let r = new f01();
				console.log("new 调用返回: ", r);
			}

			function test04() {
				let a = {};
				console.log(a);
				console.log(f01.prototype, f02.prototype);
				console.log(f01.prototype === f02.prototype)
			}

			function buildCar() {
				// 判断函数是普通方式调用还是 new 方式调用:
				// 1. this instanceof arguments.callee：普通函数false, new 真
				// 2. this.constructor === arguments.calle: 普通函数false, new 真
				// 3. new.target： 普通函数调用为 undefined, new 调用为构造函数
				// 4. "use strict" 模式下, 普通函数中用 this 出现错误, 构造函数内正常

				console.log("函数内this: ", this);
				console.log("new.target: ", new.target);
				console.log("this.constructor: ", this.constructor);
				console.log("this.constructor === arguments.callee: ", this.constructor === arguments.callee);

				this.name = "宝马";
				this.price = 30;
				this.color = "红色";
				// return this;
			}

			function f01() {
				let a = 10;
				let b = 20;
				return a + b;
			}

			function f02() {

			}

			function test11() {
				let a1 = new Array();
				let a2 = [];
				let a3 = ["Apple", "Pear", "Orange"];

				console.log(a3);
			}

			function test12() {
				let a1 = ["Apple", "Pear"];
				console.log(a1);

				a1.push("Orange");
				console.log(a1);

				a1.pop();
				console.log(a1);

				a1.unshift("Banana");
				console.log(a1);

				a1.shift();
				console.log(a1);
			}

			function test13() {
				let a1 = ["Apple", "Pear", "Orange"];

				console.log("for i 遍历 ===");
				for (let i = 0; i < a1.length; i++) {
					console.log(a1[i]);
				}

				console.log("for in 遍历 ===");
				for (let index in a1) {
					console.log(index + " = " + a1[index]);
				}

				console.log("for of 遍历 ===");
				for (item of a1) {
					console.log(item);
				}

				console.log("forEach 遍历 ===");
				a1.forEach((item, index) => {
					console.log(index + " = " + item)
				})
			}

			function test14() {
				let a1 = ["苹果", "香蕉", "桔子", "梨", "菠萝", "西瓜"];
				console.log(a1);

				let a2 = a1.slice(0, 2);
				console.log(a2);
			}

			function test15() {
				let a1 = ["苹果", "香蕉", "桔子", "梨", "菠萝", "西瓜"];
				console.log(a1);

				// 参1: 开始位置，参2: 删除数量
				let a2 = a1.splice(0, 2);
				console.log(a1, a2);

				// 替换元素
				a2 = a1.splice(0, 1, "核桃", "草莓");
				console.log(a1, a2);
				1
			}

			function test16() {
				let a1 = ["苹果", "香蕉", "桔子", "梨", "菠萝", "西瓜"];
				console.log(a1);
				for (let i = 0; i < a1.length; i++) {
					console.log(i, a1.length, a1.splice(i, 1));
				}
			}

			function test05() {
				let user = {
					name: "Tom",
					age: 20
				};

				console.log("直接调用() ===");
				f21("篮球", "学生");


				console.log("call 调用 ===");
				f21.call(user, "足球", "老师");

				console.log("apply 调用 ===");
				f21.apply(user, ["做饭", "厨师"]);

				console.log("bind 后再调用 ===");
				let temp = f21.bind(user, "旅游", "导游");
				temp();
			}

			function f05(hobby, vocation) {
				console.log(this);
				// console.log(arguments.caller);
				console.log("爱好: " + hobby + " , 职业: " + vocation);
			}

			function test21() {
				function Car(name) {
					this.name = name;
				}
				Car.prototype.showName = function() {
					console.log(this.name);
				}

				function ECar(name, energy) {
					// this.name = name;
					Car.call(this, name);
					console.log(this);
					this.energy = energy;
				}

				// 方式一
				// ECar.prototype.__proto__ = Car.prototype;
				// 方式二
				ECar.prototype = new Car();
				ECar.prototype.constructor = ECar;
				
				ECar.prototype.showEnergy = function() {
					console.log(this.energy);
				}

				var c1 = new Car("普通汽车");
				// c1.showName();
				console.log(c1);

				var c2 = new ECar("电动车", 50);
				// c2.showName();
				// c2.showEnergy();
				console.log(c2);

			}
		</script>
	</body>
</html>
